package com.basker.pisces.domain.entity.data;

import org.springframework.beans.factory.annotation.Autowired;

import com.basker.pisces.core.meta.IDataObjectMeta;
import com.basker.pisces.core.repository.IDataRepository;
import com.basker.pisces.domain.entity.event.subcriber.InitialValueHanlder;
import com.basker.pisces.domain.entity.meta.BeanEntity;

public class BeanDataEntity<TDataObject> extends AbstractDataEntity {

    @Autowired(required = false)
    private IDataRepository repository;

    public BeanDataEntity(BeanEntity<TDataObject> entity) {
        this.setEntity(entity);
        this.addDefaultSubcriber();
    }

    public BeanDataEntity(BeanEntity<TDataObject> entity, IDataRepository repository) {
        this.repository = repository;
        this.setEntity(entity);
        this.addDefaultSubcriber();
    }

    @Override
    public TDataObject createDataObject() {
        @SuppressWarnings("unchecked")
        TDataObject dataObject = (TDataObject) super.createDataObject();
        return dataObject;
    }

    @Override
    public TDataObject getDataObject() {
        @SuppressWarnings("unchecked")
        TDataObject dataObject = (TDataObject) super.getDataObject();
        return dataObject;
    }

    @Override
    public IDataRepository getDataRepository() {
        return repository;
    }

    @Override
    public TDataObject input(Object inputObject) {
        @SuppressWarnings("unchecked")
        TDataObject dataObject = (TDataObject) super.input(inputObject);
        return dataObject;
    }

    @Override
    public TDataObject input(Object inputObject, InputOption option) {
        @SuppressWarnings("unchecked")
        TDataObject dataObject = (TDataObject) super.input(inputObject, option);
        return dataObject;
    }

    @Override
    public TDataObject loadDataObject(Object pkValue) {
        IDataObjectMeta dataObjectMeta = this.getEntity().getDataObjectMeta();
        Object dataObject = this.repository.loadForUpdate(dataObjectMeta, pkValue);

        if (dataObject == null) {
            this.throwStaleObjectException(pkValue);
        }

        this.setDataObject(dataObject);
        @SuppressWarnings("unchecked")
        TDataObject bean = (TDataObject) dataObject;

        return bean;
    }

    private void addDefaultSubcriber() {
        this.eventPublisher.addSubcriber(new InitialValueHanlder());
    }

}
